package com.fjwt.gz.thirdSdk.yangyu;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.third.bo.VirtualGoodsSupplierBo;
import com.fjwt.gz.core.third.interfaces.OutSideSupplierService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Map;
import java.util.TreeMap;

/**
 * 洋芋网络供应商服务接口
 */
@Slf4j
@Service
public class YangYuWangLuoOutSideSupplierService implements OutSideSupplierService {


    private static final String logPrefix = "【洋芋网络】";
    // 外部请求地址
    /**
     * 设置商品回调地址(最多可设置三条)
     **/
    public static final String SET_GOODS_NOTIFY_URL = "/dockapiv3/user/seturl";
    /**
     * 获取全部商品信息(分页，限速2秒一次)
     **/
    public static final String GET_ALL_GOODS_URL = "http://public.kky.v3.api.kakayun.vip/dockapiv3/goods/all";
    /**
     * 获取单个商品信息(限速5秒一次)
     **/
    public static final String GET_GOODS_URL = "http://public.kky.v3.api.kakayun.vip/dockapiv3/goods/details";
    /**
     * 商品订阅
     **/
    public static final String GOODS_SUBSCRIBE_URL = "/dockapiv3/goods/subscribe";
    /**
     * 商品取消订阅
     **/
    public static final String GOODS_UNSUBSCRIBE_URL = "/dockapiv3/goods/cancelsubscribe";
    /**
     * 下单接口
     **/
    public static final String CREATE_ORDER_URL = "/dockapiv3/order/create";
    /**
     * 订单查询接口
     **/
    public static final String QUERY_ORDER_URL = "/dockapiv3/order/get";


    /**
     * 设置商品回调地址
     */
    @Override
    public JSONObject setGoodsNotifyUrl(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("receiveurl", jsonObject.getString("notifyUrl"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            return post(reqJson, configJson.getString("domain") + SET_GOODS_NOTIFY_URL);
        } catch (Exception e) {
            log.info("设置商品回调地址异常");
            throw new BizException("设置商品回调地址异常");
        }
    }

    /**
     * 获取全部商品信息
     */
    @Override
    public JSONObject getAllGoods(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("page", jsonObject.getInteger("page"));
        reqJson.put("limit", jsonObject.getInteger("limit"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            log.info("{}拉取全部商品请求参数：{}", logPrefix, reqJson.toJSONString());
            return post(reqJson, GET_ALL_GOODS_URL);
        } catch (Exception e) {
            log.info("获取全部商品信息异常");
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 获取单个商品信息
     */
    @Override
    public JSONObject getGoods(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("goodsid", jsonObject.getInteger("goodsId"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            return post(reqJson, GET_GOODS_URL);
        } catch (Exception e) {
            log.info("获取单个商品信息异常");
            throw new BizException("获取单个商品信息异常");
        }
    }

    /**
     * 商品订阅
     */
    @Override
    public JSONObject goodsSubscribe(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("goodsid", jsonObject.getInteger("goodsId"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            return post(reqJson, configJson.getString("domain") + GOODS_SUBSCRIBE_URL);
        } catch (Exception e) {
            log.info("商品订阅异常");
            throw new BizException("商品订阅异常");
        }
    }

    /**
     * 商品取消订阅
     */
    @Override
    public JSONObject goodsUnSubscribe(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("goodsid", jsonObject.getInteger("goodsId"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            return post(reqJson, configJson.getString("domain") + GOODS_UNSUBSCRIBE_URL);
        } catch (Exception e) {
            log.info("商品取消订阅异常");
            throw new BizException("商品取消订阅异常");
        }
    }

    /**
     * 下单
     */
    @Override
    public JSONObject createOrder(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("goodsid", jsonObject.getInteger("goodsId"));
        reqJson.put("buynum", jsonObject.getInteger("buyNum"));
        reqJson.put("usorderno", jsonObject.getString("sysUserNo")); //系统订单号
        reqJson.put("attach", jsonObject.getString("attach"));// 充值账号
        reqJson.put("callbackurl", jsonObject.getString("notifyUrl"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            JSONObject response = post(reqJson, configJson.getString("domain") + CREATE_ORDER_URL);
            if (ObjectUtils.isEmpty(response) || ObjectUtils.isEmpty(response.getJSONObject("data"))) {
                throw new BizException(response.getString("msg"));
            }
            return response.getJSONObject("data");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new BizException("下单异常");
        }
    }

    /**
     * 订单查询接口
     */
    @Override
    public JSONObject queryOrder(JSONObject jsonObject, VirtualGoodsSupplierBo virtualGoodsSupplierBo) {
        JSONObject configJson = JSONObject.parseObject(virtualGoodsSupplierBo.getAuthConfig());

        JSONObject reqJson = new JSONObject();
        reqJson.put("userid", configJson.getInteger("userId"));
        reqJson.put("timestamp", DateUtil.date().getTime() / 1000);
        reqJson.put("usorderno", jsonObject.getString("sysUserNo")); //系统订单号
        reqJson.put("orderno", jsonObject.getString("orderNo"));
        reqJson.put("sign", getMD5Sign(reqJson, configJson.getString("key")));

        try {
            JSONObject response = post(reqJson, configJson.getString("domain") + QUERY_ORDER_URL);
            if (ObjectUtils.isEmpty(response) || ObjectUtils.isEmpty(response.getJSONObject("data"))) {
                throw new BizException(response.getString("msg"));
            }
            return response.getJSONObject("data");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new BizException("订单查询接口异常");
        }
    }


    /**
     * post请求
     */
    private JSONObject post(JSONObject param, String url) throws Exception {
        HttpResponse response = null;
        try {
            HttpRequest body = HttpRequest.post(url)
                    .header("Content-Type", "application/json;charset=utf-8")
                    .timeout(30000)
                    .body(JSONUtil.toJsonStr(param));
            response = body.execute();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException("网络连接异常,请稍后重试");
        }
        if (response == null || response.body() == null) {
            throw new BizException("网络连接异常,请稍后重试");
        }
        log.debug("响应结果：{}", response.body());
        JSONObject body = JSONObject.parseObject(response.body());
        if (1 != body.getInteger("code")) {
            throw new BizException(body.getString("msg"));
        }
        return body;
    }

    /**
     * MD5加密
     */
    private String getMD5Sign(JSONObject params, String key) {
        // 排序
        TreeMap<String, String> sortedParams = new TreeMap<>();
        for (String paramKey : params.keySet()) {
            sortedParams.put(paramKey, params.getString(paramKey));
        }

        // 拼接参数
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(entry.getKey()).append("=").append(entry.getValue());
        }
        // 拼接key
        sb.append(key);
        log.info("拼接参数：{}", sb);
        // md5加密
        String sign = DigestUtils.md5DigestAsHex(sb.toString().getBytes());
        log.info("md5加密后参数：{}", sign);
        return sign;
    }
}
